home *** CD-ROM | disk | FTP | other *** search
- Date: Fri, 22 Jul 94 03:16 CDT
- From: ekl@sdf.lonestar.org (Evan K. Langlois)
- To: gem-list@world.std.com
- Subject: BUTTON CODE
- Precedence: bulk
-
-
- /* NOTE This program uses printf, and it really shouldn't. But I want
- you to compile this and see that you really can wait on any buttons
- and that a right-left combination is NOT needed. I used printf so
- I wouldn't have to post a RSC file. This program is only meant to
- demonstrate how to recieve mouse button events. It is NOT meant to
- show how to properly code a GEM application - see ST-Pro-GEM for good
- GEM programming.
- */
-
- #include <osbind.h>
- #include <gemfast.h>
- #include <aesbind.h>
- #include <stdio.h>
-
- void main (void) {
-
- register int i, bb;
- int quit = 0, mes[8], ky, t, press, x, y, b, d, nb, k, rc, app_id;
-
- app_id = appl_init();
-
- /* This may help multitasking, and/or the double-click-event bug, and it
- sets up some defaults, like starting button mask. Its not needed */
-
- evnt_multi(0x23,1,1,1,0,0,0,0,0,0,0,0,0,0,mes,150L,&x,&y,&nb,&k,&ky,&t);
-
- while (!quit) {
-
- /* HOW TO WAIT ON ANY BUTTON !
-
- The second parameter to evnt_multi tells how many button clicks to
- wait for. This is the maximum number, so make it big. If you want to
- recieve a double click, make it at least 2. Big numbers are no problem.
- The high byte is set ON (OR with 0x0100 or add 256) to make this a
- reverse button event - we wait for a negative condition. I'm not sure
- if GEM will still delay for a second click if you set the low byte to 1,
- and we NEED this delay for "presses" so leave the byte at 2 to be safe.
-
- The third parameter tells the mask of buttons that you are waiting on.
- ALL BUTTONS ARE WAITED FOR! You wait for all buttons, not either button.
- Normally you use 0x01 for the left button, but when using the negative
- event, you can handle more buttons than one, so make it 0x7F for all 8!
-
- The third is a button mask, 0 for up, 1 for down, for each button, same
- as the button return word, and the button mask in the previous parameter.
- Normally this is a 1, waiting for the left mouse button to be down. In
- this trick you make it a 0 (all buttons up).
-
- The trick is simple, wait for ALL buttons to NOT be up. The event fires
- when ALL the buttons are not up - or when any one button is down. Now,
- a common mistake is to leave the third parameter a constant, which means
- the evnt_multi falls through as long as the person holds the button down.
- Make the parameter the old button mask, and you'll get an event when any
- one button changes state. Note that you'll get two events for one click
- unless you change the button mask and remember that on a normal click,
- the mouse has been checked for a double-click, so &b is when the event
- occured, not the current button state.
-
- By using graf_mkstate to poll the current state of the button, we can
- tell if the button is already up. If its already released, then we have
- a single click, and we change our mask so that we don't get a button
- up event. Otherwise, we see if there is a draggable object or menu.
- */
- rc = evnt_multi (0x03, 0x102,0x7F,nb, 0,0,0,0,0, 0,0,0,0,0, mes,
- 0L, &x, &y, &b, &k, &ky, &t);
-
- if (rc & MU_KEYBD) /* Keyboard event, quit app */
- quit = 1;
-
- if (rc & MU_BUTTON) {
- /* See what window to "send" the click to here, with
- * wind_find() and a custom lookup - how is up to you.
- *
- * graf_mkstate() is called here because it sets the
- * evnt_multi input button state and gives us the
- * current state to compare to the evnt_multi output
- */
-
- graf_mkstate (&d,&d,&press,&d); /* New button state */
-
-
- /* Here we test and compare button masks, bit-by-bit! */
-
- for (i=0; i < 8; i++) {
- bb = (1 << i); /* A mask ! */
- if ((nb & bb) != (b & bb)) { /* An event? */
- if (b & bb)
- if (press & bb)
- printf ("Press button #%d @ %d,%d\n",i,x,y);
- else if (t > 1)
- printf ("D-Click button #%d @ %d,%d\n",i,x,y);
- else
- printf ("Click button #%d @ %d,%d\n",i,x,y);
- else
- printf ("Release button #%d @ %d,%d\n",i,x,y);
- }
- }
- nb = press;
- }
- }
- appl_exit();
- Pterm0();
- }
-
-
- /* A press means begin drag or group select (button 0/left) or pop-up a
- * menu (button 1/right) or it may mean to begin some rectangle tricks. A
- * graphics program would use a press to turn on mouse rectangles, and
- * would apply a brush when the rectangle event fires, and would turn off
- * the rectangle event handling when a release event occurs. A release
- * event signals where a pop-up menu was selected, or where an item was
- * dropped.
- *
- * Remember that you did not get an event unless the button mask put in
- * to evnt_multi is different from that coming out of evnt_multi.
- *
- * A window top is a click if there is a selectable and completely
- * UNOBSCURED object under the mouse pointer in the window being topped.
- * Otherwise top the window! Objects must be completely visible!
- *
- *
- * A press can wait on rectangles do the operation on a release within
- * the object, while entering and exiting the object selects and deselects
- * the object, much like form_do() - try it!
- *
- * Don't call graf_mkstate or another polling routine - always use the
- * mouse coordinates at the time of the event! The code above is very
- * non-modal. You can pop-up a menu with a right button, then realizing
- * you should have selected an icon, you click it with the left button,
- * then release the right button on the menu item you prefer. Button
- * events are completely independant! You are also free to allow the
- * right button OR left button to select buttons (nice for left handed
- * users).
- *
- * Enjoy the code!
- */
-
-